package agent;


import agent.strategy.StrategyBuilders;
import agent.strategy.StrategyExecutor;
import api.*;
import com.google.common.base.Optional;
import org.apache.axis2.AxisFault;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import utils.ConsoleDisplay;
import utils.Display;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * User: Darren
 * Date: 6/01/13
 * Time: 7:28 PM
 */
class Agent {
    static Logger logger = Logger.getLogger(Agent.class);
    private ScheduledExecutorService scheduler;
    private Display display;
    private APIFactory apiFactory;
    private MarketFactory marketFactory;
    private StrategyBuilders strategiesBuilders;
    private StrategyExecutor strategyExecutor = new StrategyExecutor();

    public static enum MenuItem {
        SELECT_BETFAIR_MARKET_AND_VIEW("Select Betfair market and view"),
        SELECT_BETFAIR_MARKET_AND_VIEW_REPEATEDLY("Select Betfair market and view repeatedly");

        String description;
        MenuItem(String description) {
            this.description = description;
        }
    }
    private final String[] menuDescriptions = new String[MenuItem.values().length];

    Agent() throws AxisFault, RuntimeException {
        scheduler = Executors.newScheduledThreadPool(2);
        display = new ConsoleDisplay();
        apiFactory = new APIFactory(scheduler, display);
        marketFactory = new MarketFactory();
        strategiesBuilders = new StrategyBuilders(apiFactory, marketFactory, display, scheduler);
        buildMenu();
    }

    private void buildMenu() {
        int i = 0;
        for (MenuItem item: MenuItem.values()) {
            menuDescriptions[i] = "[ " + i++ + " ], " + item.description;
        }
    }

    private void betfairExchangeLogin() {
        strategyExecutor.executeStrategy(strategiesBuilders.buildBefairExchangeLogin.build());
    }

    private void betfairExchangeLogout(int status) {
        strategyExecutor.executeStrategy(strategiesBuilders.buildBetfairExchangeLogout.build());
        System.exit(status);
    }

    private void selectBetfairMarketAndView() {
        strategyExecutor.executeStrategy(strategiesBuilders.buildSelectBefairMarketAndView.build());
    }

    private void selectBetfairMarketAndViewRepeatedlyForOneMinute() {
        strategyExecutor.executeStrategy(strategiesBuilders.buildSelectBetairMarketAndViewRepeatedlyForOneMinute.build());
    }

    public static void main(String[] args) {
        PropertyConfigurator.configure(args[0]);
        logger.info("Agent starting...");
        Optional<Agent> agentOptional = Optional.absent();
        try {
            agentOptional = Optional.of(new Agent());
            agentOptional.get().betfairExchangeLogin();
            int operation;
            do {
                operation = agentOptional.get().display.getChoiceAnswer("Select operation [-1 to quit]:",
                        agentOptional.get().menuDescriptions, -1, MenuItem.values().length -1);
                if (operation > -1) {
                    MenuItem menuItem = MenuItem.values()[operation];
                    switch (menuItem) {
                        case SELECT_BETFAIR_MARKET_AND_VIEW:
                            agentOptional.get().selectBetfairMarketAndView();
                            break;
                        case SELECT_BETFAIR_MARKET_AND_VIEW_REPEATEDLY:
                            agentOptional.get().selectBetfairMarketAndViewRepeatedlyForOneMinute();
                            break;
                        default:
                    }
                }
            } while (operation > -1);
            agentOptional.get().betfairExchangeLogout(0);
        } catch (AxisFault e) {
            e.printStackTrace();
            System.exit(1);
        } catch(RuntimeException e) {
            e.printStackTrace();
            if (agentOptional.isPresent()) {
                agentOptional.get().betfairExchangeLogout(1);
            } else {
                System.exit(1);
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (agentOptional.isPresent()) {
                agentOptional.get().betfairExchangeLogout(1);
            } else {
                System.exit(1);
            }
        }
    }
}
